/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using CompilationException = System.Qizx.Api.CompilationException;
using Lexer = System.Qizx.XQuery.Impl.Lexer;
namespace System.Qizx.Api.Util {


    /// <summary> Iterator on tokens of a XQuery script. 
    /// Used for implementing syntax coloring in Qizx Studio.
    /// <p>Returns the lexical group and the position and size of each token.
    /// </summary>
    public class LexicalTokenizer : Lexer {
        /// <summary> Returns the text of the current token: null if the end is reached.</summary>
        virtual public string TokenValue {
            get {
                return source.Substring(tokenStart, (tokenEnd) - (tokenStart));
            }

        }
        /// <summary> Returns the start position of the current token.</summary>
        virtual public int TokenStart {
            get {
                return tokenStart;
            }

        }
        /// <summary> Returns the length of the current token.</summary>
        virtual public int TokenLength {
            get {
                return tokenEnd - tokenStart;
            }

        }
        /// <summary> Size of leading space before the current token.</summary>
        virtual public int SpaceLength {
            get {
                return tokenStart - prevTokenEnd;
            }

        }
        /// <summary> Gets the space that is before the current token. Returns null if no
        /// space.
        /// </summary>
        virtual public string Space {
            get {
                if (tokenStart <= prevTokenEnd)
                    return null;
                return source.Substring(prevTokenEnd, (tokenStart) - (prevTokenEnd));
            }

        }
        //    private int curToken;
        private int prevTokenEnd = 0;

        // lexical categories:
        /// <summary>Lexical category of element constructors. </summary>
        new public static readonly int LC_TAG;
        /// <summary>Lexical category of whitespace. </summary>
        new public static readonly int LC_SPACE;
        /// <summary>Lexical category of numeric literals. </summary>
        new public static readonly int LC_NUMBER;
        /// <summary>Lexical category of string literals. </summary>
        new public static readonly int LC_STRING;
        /// <summary>Lexical category of others tokens. </summary>
        new public static readonly int LC_MISC;
        /// <summary>Lexical category of identifiers. </summary>
        new public static readonly int LC_NAME;
        /// <summary>Lexical category of reserved keywords. </summary>
        new public static readonly int LC_KEYWORD;
        /// <summary>Lexical category of XQuery comments. </summary>
        new public static readonly int LC_COMMENT;
        /// <summary>Lexical category of XQuery pragmas. </summary>
        new public static readonly int LC_PRAGMA;
        /// <summary>Lexical category of XQuery function calls. </summary>
        new public static readonly int LC_FUNCTION;

        /// <summary> Constructs a tokenizer of a XQuery script.</summary>
        /// <param name="script">source XQuery script to tokenize
        /// </param>
        public LexicalTokenizer(string script) {
            startLexer(script);
            showComments = true;
            // debug = true;
        }

        /// <summary> Moves to next token and returns its category.</summary>
        /// <returns> token code (LC_xxx)
        /// </returns>
        /// <throws>  CompilationException if parsing error </throws>
        public override int nextToken() {
            prevTokenEnd = tokenEnd;
            int curToken = getToken();
            if (curToken == T_END)
                return 0;
            return getTokenCategory(curToken);
        }

        internal virtual void parsedPragma(int location, string prefix, string localName, string body) {
        }

        internal virtual void parsedExtension(int location, string prefix, string localName, string body) {
        }
        static LexicalTokenizer() {
            LC_TAG = Lexer.LC_TAG;
            LC_SPACE = Lexer.LC_SPACE;
            LC_NUMBER = Lexer.LC_NUMBER;
            LC_STRING = Lexer.LC_STRING;
            LC_MISC = Lexer.LC_MISC;
            LC_NAME = Lexer.LC_NAME;
            LC_KEYWORD = Lexer.LC_KEYWORD;
            LC_COMMENT = Lexer.LC_COMMENT;
            LC_PRAGMA = Lexer.LC_PRAGMA;
            LC_FUNCTION = Lexer.LC_FUNCTION;
        }
    }
}